package com.tticar.invmanager.service.impl;

import com.baomidou.mybatisplus.entity.Column;
import com.baomidou.mybatisplus.entity.Columns;
import com.baomidou.mybatisplus.mapper.Condition;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.tticar.invmanager.entity.SysResource;
import com.tticar.invmanager.entity.SysRoleResource;
import com.tticar.invmanager.entity.vo.MyPage;
import com.tticar.invmanager.mapper.SysResourceMapper;
import com.tticar.invmanager.mapper.SysRoleResourceMapper;
import com.tticar.invmanager.service.ISysResourceService;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 资源管理 服务实现类
 * </p>
 *
 * @author joeyYan
 * @since 2018-06-17
 */
@Service
public class SysResourceServiceImpl extends ServiceImpl<SysResourceMapper, SysResource> implements ISysResourceService {

    @Autowired
    private SysRoleResourceMapper roleResourceMapper;

    @Override
    public List getTree(Long roleId, Long targetRoleId) {
        List targetRIds = null, resouceIds = null;
        if (targetRoleId != null) {
            Wrapper<SysRoleResource> w = Condition.create();
            w.setSqlSelect(Column.create().column(SysRoleResource.RESOURCE_ID));
            w.eq(SysRoleResource.ROLE_ID, targetRoleId);
            targetRIds = roleResourceMapper.selectObjs(w);
        }

        if (roleId == 1) {
            return recursion(null, 0l, null, targetRIds);
        } else {
            Wrapper<SysRoleResource> w = Condition.create();
            w.setSqlSelect(Column.create().column(SysRoleResource.RESOURCE_ID));
            w.eq(SysRoleResource.ROLE_ID, roleId);
            w.isNotNull(roleId == 2, SysRoleResource.TENANT_ID);
            resouceIds = roleResourceMapper.selectObjs(w);
            //未配置权限的普通用户只能看首页
            if (resouceIds == null || resouceIds.size() < 1) {
                return null;
            }
            return recursion(null, 0l, resouceIds, targetRIds);
        }
    }

    @Override
    public Page selectPage(SysResource entity, MyPage<SysResource> page) {
        Wrapper wrapper = new EntityWrapper();
        Columns columns = Columns.create()
                .column("*")
                .column("(select case count(1) when 0 then 'open' else 'closed' end from sys_resource t where t.pid=sys_resource.id)", "state");
        wrapper.setSqlSelect(columns);
        wrapper.orderBy(SysResource.SORT, false);
        wrapper.eq(SysResource.PID, entity.getId());
        wrapper.like(Strings.isNotEmpty(entity.getName()), SysResource.NAME, entity.getName());
        return this.selectMapsPage(page, wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Long> ids) {
        List list = new ArrayList();
        for (Long id : ids) {
            SysResource sysResource = new SysResource();
            sysResource.setId(id);
            //删除为-1，区分删除和禁用
            sysResource.setStatus(-1);
            list.add(sysResource);
        }
        this.updateBatchById(list);
    }

    private List recursion(List<Map<String, Object>> list, Long pid, List resouceIds, List targetRIds) {
        Wrapper<SysResource> wrapper = Condition.create().orderBy(SysResource.SORT);
        Columns columns = Columns.create()
                .column("*")
                .column("name", "text")
                .column("(select count(1) from sys_resource t where t.pid=sys_resource.id)", "ccnt");
        wrapper.setSqlSelect(columns);
        wrapper.eq(SysResource.PID, pid);
        wrapper.ne(SysResource.TYPE, 3);
        wrapper.in(resouceIds != null, SysResource.ID, resouceIds);
        List<Map<String, Object>> _list = this.selectMaps(wrapper);
        list = list == null ? _list : list;
        for (Map<String, Object> map : _list) {
            map.put("checked", targetRIds != null && targetRIds.contains(map.get("id")));
            Long ccnt = (Long) map.get("ccnt");
            if (ccnt > 0) {
                pid = (Long) map.get("id");
                map.put("children", this.recursion(list, pid, resouceIds, targetRIds));
            }
        }
        return _list;
    }

}
